我们都知道著名的 VLOOKUP() 函数可以帮助我们组合来自不同表的数据。然而,这个函数有一个显着的缺点——它不能组合相似的值,也就是说,如果单词中有错误,那么就不会匹配。
为了能够组合近似值,我们可以创建自己的函数。我们将其称为 FuzzyLookup()。
假设我们有两个列表。两者具有大致相同的元素,但它们的写法可能略有不同。任务是为第一个列表中的每个元素找到第二个列表中最相似的元素,即实现对最近的最大相似文本的搜索。
在这种情况下,最大的问题是如何考虑“相似性”的标准。只是匹配字符的数量?是连续比赛的次数吗?应该考虑字符大小写还是空格?如何处理短语中单词的不同排列?有很多选择,并且没有单一的解决方案 - 对于每种情况,其中一个会比其他更好。
在我们的例子中,我们实现了最简单的选项 - 按字符匹配的最大数量进行搜索。它并不完美,但在大多数情况下都可以很好地工作。
加上 函数FuzzyLookup ,打开菜单 Tools - Macros - Edit Macros... , 选择 模块1 并将以下文本复制到模块中:
Function FuzzyLOOKUP(LookupValue As String, SrcTable As Variant, Optional SimThreshold As Single) As String
' moonexcel.com.ua
Dim Str As String
Dim CellArray As Variant
Dim StrArray As Variant
If IsMissing(SimThreshold) Then SimThreshold = 0
Str = LCase(LookupValue)
StrArray = Split(Str)
StrExt = UBound(StrArray)
For Each Cell In SrcTable
CellArray = Split(LCase(Cell))
CellExt = UBound(CellArray)
CellRate = 0
' 我们检查搜索短语中的每个单词
For x = 0 To StrExt
StrWord = StrArray(x)
If Len(StrWord) = 0 Then GoTo continue_x
MaxStrWordRate = 0
' 我们检查原始值表中下一个单元格中的每个单词
For i = 0 To CellExt
CellWord = CellArray(i)
If Len(CellWord) = 0 Then GoTo continue_i
FindCharNum = OccurrenceNum(StrWord, CellWord)
StrWordRate = FindCharNum / Max(Len(StrWord),Len(CellWord))
If StrWordRate > MaxStrWordRate Then MaxStrWordRate = StrWordRate
continue_i:
Next i
CellRate = CellRate + MaxStrWordRate
continue_x:
Next x
' 我们保留最佳匹配
If CellRate > MaxCellRate Then
MaxCellRate = CellRate
BestCell = Cell
FindCharNum = OccurrenceNum(Str, Cell)
SimRate = FindCharNum / Max(Len(Str),Len(Cell))
End If
Next Cell
IF SimRate >= SimThreshold Then
IF SimThreshold = -1 Then
ReturnValue = BestCell + " (" + Format(SimRate, "0.00") + ")"
ElseIf SimThreshold = -2 Then
ReturnValue = Format(SimRate, "0.00")
Else
ReturnValue = BestCell
End If
Else
ReturnValue = ""
End If
FuzzyLOOKUP = ReturnValue
End Function
Function OccurrenceNum(ByVal SourceString As String, ByVal TargetString As String)
For i = 1 To Len(SourceString)
' 我们正在寻找每个符号的出现次数
Position = InStr(1, TargetString, Mid(SourceString, i, 1), 1)
' 我们增加巧合的计数器
If Position > 0 Then
Count = Count + 1
' 删除找到的符号
TargetString = Left(TargetString, Position - 1) + Right(TargetString, Len(TargetString) - Position)
End If
Next i
OccurrenceNum = Count
End Function
Function Max(ByVal value1 As Variant, ByVal value2 As Variant)
If value1 > value2 Then
Result = value1
Else
Result = value2
End If
Max = Result
End Function
接下来,关闭 Macro Editor 并返回工作表 LibreOffice Calc - 现在您可以使用我们的新功能 FuzzyLookup() 。
您还可以使用该功能 模糊查找() 通过安装免费扩展 YouLibreCalc.oxt 或其全功能版本 YLC_Utilities.oxt 。
之后,该功能将在 LibreOffice Calc 中打开的所有文件中可用。